package com.thornbird.vehiclerecycling.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static final String DATE_FORMAT = "yyyy-MM-dd";

    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String CHINESE_DATE_FORMAT = "yyyy年M月d日";

    public static Date addDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    public static Date addMonths(Date date, int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, months);
        return calendar.getTime();
    }

    public static String formatDate(Date date) {
        return formatDate(date, false);
    }

    public static String formatDate(Date date, boolean includeTime) {
        return formatDate(date, includeTime ? DATETIME_FORMAT : DATE_FORMAT);
    }

    public static String formatDate(Date date, String format) {
        String text = "";
        if (date == null) {
            return text;
        }

        DateFormat dateFormat = new SimpleDateFormat(format);
        text = dateFormat.format(date);
        return text;
    }

    public static Date getData(int year, int month, int dayOfMonth) {
        return getData(year, month, dayOfMonth, 0, 0, 0, 0);
    }

    public static Date getData(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) {
        return getData(year, month, dayOfMonth, hourOfDay, minute, second, 0);
    }

    public static Date getData(int year, int month, int dayOfMonth,
                               int hourOfDay, int minute, int second, int millisecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, millisecond);
        return calendar.getTime();
    }

    public static Date getDateWithTime(Date date, int hourOfDay, int minute, int second, int millisecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (hourOfDay >= 0) {
            calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
        }
        if (minute >= 0) {
            calendar.set(Calendar.MINUTE, minute);
        }
        if (second >= 0) {
            calendar.set(Calendar.SECOND, second);
        }
        if (millisecond >= 0) {
            calendar.set(Calendar.MILLISECOND, millisecond);
        }
        return calendar.getTime();
    }

    public static int getDayInterval(Date startDate, Date endDate) {
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        endCalendar.setTime(endDate);
        int startDay = startCalendar.get(Calendar.DAY_OF_YEAR);
        int endDay = endCalendar.get(Calendar.DAY_OF_YEAR);
        int startYear = startCalendar.get(Calendar.YEAR);
        int endYear = endCalendar.get(Calendar.YEAR);
        if (startYear != endYear) {
            int days = 0;
            for (int i = startYear; i < endYear; i++) {
                if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
                    days += 366;
                } else {
                    days += 365;
                }
            }
            return days + (endDay - startDay);
        } else {
            return endDay - startDay;
        }
    }

    public static int getDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static int getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    public static Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return addDays(getFirstDayOfMonth(addMonths(calendar.getTime(), 1)), -1);
    }

    public static Date getLastDayOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR), 11, 31);
        return calendar.getTime();
    }

    public static Date getEarlyMorningDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getMidnightDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static boolean isSameDate(Date date1, Date date2) {
        if (date1 == null || date2 == null) return false;
        return getMidnightDate(date1).compareTo(getMidnightDate(date2)) == 0;
    }

    public static Date parseDate(String dateText) {
        return parseDate(dateText, false);
    }

    public static Date parseDate(String dateText, boolean includeTime) {
        return parseDate(dateText, includeTime ? DATETIME_FORMAT : DATE_FORMAT);
    }

    public static Date parseDate(String dateText, String format) {
        Date date = null;
        dateText = dateText == null ? "" : dateText.trim();
        if (dateText.isEmpty()) {
            return date;
        }

        DateFormat dateFormat = new SimpleDateFormat(format);
        try {
            date = dateFormat.parse(dateText);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

}
